package com.adee.java;

import com.adee.util.Utils;

import java.util.concurrent.locks.LockSupport;

/**
 * LockSupport.park()：
 * 尝试获取一个许可，如果没有则阻塞当前线程，响应中断；以下情况会返回
 * 1.调用unpark(Thread thread)获得许可，这个unpark操作可以在park之前或者之后，如果park之前已经获得了许可，则调用了park会发上返回
 * 2.当前线程被中断(interrupt())，返回时不会抛出异常
 * 3.因为虚假唤醒而返回
 *
 * LockSupport.unpark()：
 * 提供一个许可，唤醒线程的方法就这一个。
 * 1.如果thread 之前没有持有许可，则让thread 线程持有一个，如果这前有许可了，那么数量不会增加
 * 2.如果thread 之前因调用park()而被挂起，则调用unpark()后，该线程会被唤醒。
 * 3.如果thread 之前没有调用park()，则调用unpark()方法后，后续再一次调用park()方法时，其会立刻返回。
 */
public class Test039_LockSupport {
    public static void main(String[] args) throws Exception {
        test2();
    }

    /**
     * 测试先unpark后park
     */
    public static void test1() throws InterruptedException {
        Thread t1 = new Thread(()->{
            System.out.println("线程t1启动");
            Utils.sleep(1);
            System.out.println("t1中执行park()");
            LockSupport.park();
            System.out.println("t1中执行park()返回");
        });
        Thread t2 = new Thread(()->{
            System.out.println("线程t2启动");
            System.out.println("t2中unpark(t1)");
            LockSupport.unpark(t1);
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }

    /**
     * 测试park能够响应中断，不抛出异常，直接返回
     */
    public static void test2() throws InterruptedException {
        Thread t1 = new Thread(()->{
            System.out.println("线程t1开始park...");
            // 当前线程t1阻塞中，当主线程中调用t1.interrupt()时，当前线程t1响应中断，即被中断唤醒，继续执行
            LockSupport.park();
            System.out.println("线程t1 park返回");
        });
        t1.start();
        Thread main = Thread.currentThread();
        Utils.sleep(1);
        t1.interrupt(); // 对线程t1设置中断状态
        t1.join();
    }
}
